import { FFmpeg } from '@ffmpeg/ffmpeg'
import { fetchFile, toBlobURL } from '@ffmpeg/util'

/**
 * 视频处理服务
 * 使用ffmpeg-wasm处理和转换视频
 */
export class VideoService {
  private ffmpeg: FFmpeg | null = null
  private isLoaded = false
  private baseURL = ''

  /**
   * 初始化FFmpeg实例
   */
  async init(): Promise<void> {
    if (this.ffmpeg) return

    this.ffmpeg = new FFmpeg()

    // 设置日志级别
    this.ffmpeg.on('log', ({ message }) => {
      console.log(`[FFmpeg] ${message}`)
    })

    // 设置进度回调
    this.ffmpeg.on('progress', ({ progress, time }) => {
      console.log(`[FFmpeg] Progress: ${progress * 100}%, Time: ${time / 1000}s`)
    })

    // 动态加载FFmpeg核心文件
    this.baseURL = 'https://unpkg.com/@ffmpeg/core@0.12.6/dist/umd'

    try {
      const coreURL = await toBlobURL(`${this.baseURL}/ffmpeg-core.js`, 'text/javascript')
      const wasmURL = await toBlobURL(`${this.baseURL}/ffmpeg-core.wasm`, 'application/wasm')

      await this.ffmpeg.load({
        coreURL,
        wasmURL
      })

      this.isLoaded = true
      console.log('[FFmpeg] 已加载')
    } catch (error) {
      console.error('[FFmpeg] 加载失败:', error)
      throw error
    }
  }

  /**
   * 处理视频文件
   * @param videoUrl Blob URL 格式的视频源
   * @param outputFormat 输出格式 (默认: mp4)
   * @returns 处理后的视频数据
   */
  async processVideo(videoUrl: string, outputFormat = 'mp4'): Promise<Uint8Array> {
    if (!this.ffmpeg || !this.isLoaded) {
      await this.init()
    }

    try {
      // 从Blob URL获取视频文件
      const videoFile = await fetchFile(videoUrl)

      // 写入输入文件
      await this.ffmpeg!.writeFile('input.webm', videoFile)

      // 根据输出格式选择编码器和参数
      let outputOptions: string[] = []
      const outputFileName = `output.${outputFormat}`

      if (outputFormat === 'mp4') {
        // 使用H.264编码器进行MP4转换
        outputOptions = [
          '-c:v',
          'libx264', // 视频编码器
          '-preset',
          'fast', // 编码速度预设
          '-crf',
          '23', // 质量参数 (0-51，越低质量越好)
          '-pix_fmt',
          'yuv420p', // 像素格式，确保兼容性
          '-movflags',
          '+faststart' // 优化网络播放
        ]
      } else if (outputFormat === 'webm') {
        // 使用VP9编码器
        outputOptions = [
          '-c:v',
          'libvpx-vp9', // VP9编码器
          '-crf',
          '30', // 质量参数
          '-b:v',
          '0' // 可变比特率
        ]
      } else {
        // 默认转码参数
        outputOptions = ['-c:v', 'copy']
      }

      // 处理音频
      outputOptions.push('-c:a', 'aac', '-b:a', '128k')

      // 执行转码命令
      const ffmpegArgs = ['-i', 'input.webm', ...outputOptions, outputFileName]

      await this.ffmpeg!.exec(ffmpegArgs)

      // 读取处理后的文件
      const data = await this.ffmpeg!.readFile(outputFileName)

      // 清理临时文件
      await this.ffmpeg!.deleteFile('input.webm')
      await this.ffmpeg!.deleteFile(outputFileName)

      return data
    } catch (error) {
      console.error('[FFmpeg] 处理视频失败:', error)
      throw error
    }
  }

  /**
   * 释放资源
   */
  async unload(): Promise<void> {
    if (this.ffmpeg) {
      try {
        await this.ffmpeg.terminate()
        this.ffmpeg = null
        this.isLoaded = false
        console.log('[FFmpeg] 已卸载')
      } catch (error) {
        console.error('[FFmpeg] 卸载失败:', error)
      }
    }
  }
}

// 导出单例实例
export const videoService = new VideoService()
